/**
 * Created by meiguizhinian on 2018/7/5
 * Copyright © 2018 lixiaolong. All rights reserved.
 */

//TODO:等等完成
if (!cc.sys.isNative) {
	let pTTF = cc.LabelTTF.prototype;
	pTTF.setTextColor = function (color) {
		this.setFontFillColor(color);
	};

	pTTF._ttfConfig = null;
	pTTF.setTTFConfig = function (config) {
		this._ttfConfig = config;
	};
	pTTF.getTTFConfig = function () {
		if (!this._ttfConfig) {
			this._ttfConfig = cc.ttfConfig(this.getFontName(), this.getFontSize(),
				cc.GlyphCollection.DYNAMIC, null, false, 0,
				false, false, false, false
			);
		}
		let config = cc.ttfConfig();
		Object.assign(config, this._ttfConfig);
		return config;
	};
	////////////////////////////////////////////////////////////////////////////
	pTTF.updateContent = function () {

	};

	pTTF.setAdditionalKerning = function (config) {

	};
	pTTF.setAlignment = function (hAlignment, vAlignment) {
		this.setHorizontalAlignment(hAlignment);
		this.setVerticalAlignment(vAlignment);
	};

	pTTF.enableBold = function() {

	};
	pTTF.enableGlow = function() {

	};
	pTTF.enableItalics = function() {
		this.setRotationSkewX(12);
	};
	pTTF.enableOutline = function() {
		this.enableStroke();
	};
	//pTTF.enableShadow = function(shadowColor, offset, blurRadius) {};
	pTTF.enableStrikethrough = function() {

	};
	pTTF.enableUnderline = function() {

	};
	pTTF.enableWrap = function (enable) {
		if (enable) {
			this.setDimensions(cc.size(this._maxLineWidth, 0));
		} else {
			this.setDimensions(cc.size());
		}
	};

	pTTF.setLineSpacing = function (spacing) {
		this.setLineHeight(spacing)
	};

	pTTF._maxLineWidth = 0;
	pTTF.setMaxLineWidth = function (width) {
		this._maxLineWidth = width;
		this.setDimensions(cc.size(width, 0));
	};
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	let pBMF = cc.LabelBMFont.prototype;
	pBMF._additionalKerning = 0;
	pBMF._bmfontScale = 1;
	pBMF.createFontChars = function () {
		var locStr = this._string;
		var stringLen = locStr ? locStr.length : 0;

		var self = this;
		var cmd = this._renderCmd;
		var locTexture = cmd._texture || this._texture;

		var nextFontPositionX = 0;

		var tmpSize = cc.size(0, 0);

		var longestLine = 0;

		var quantityOfLines = 1;


		var i, locCfg = self._config, locKerningDict = locCfg.kerningDict,
			locCommonH = locCfg.commonHeight, locFontDict = locCfg.fontDefDictionary;
		for (i = 0; i < stringLen - 1; i++) {
			if (locStr.charCodeAt(i) === 10) quantityOfLines++;
		}

		var totalHeight = locCommonH * quantityOfLines;
		var nextFontPositionY = -(locCommonH - locCommonH * quantityOfLines);

		var prev = -1;
		var fontDef;
		for (i = 0; i < stringLen; i++) {
			var key = locStr.charCodeAt(i);
			if (key === 0) continue;

			if (key === 10) {
				//new line
				nextFontPositionX = 0;
				nextFontPositionY -= locCfg.commonHeight;
				continue;
			}

			var kerningAmount = locKerningDict[(prev << 16) | (key & 0xffff)] || 0;
			fontDef = locFontDict[key];
			if (!fontDef) {
				cc.log("cocos2d: LabelBMFont: character not found " + locStr[i]);

				fontDef = {
					rect: {
						x: 0,
						y: 0,
						width: 0,
						height: 0
					},
					xOffset: 0,
					yOffset: 0,
					xAdvance: 0
				};
			}

			var rect = cc.rect(fontDef.rect.x, fontDef.rect.y, fontDef.rect.width, fontDef.rect.height);
			rect = cc.rectPixelsToPoints(rect);
			rect.x += self._imageOffset.x;
			rect.y += self._imageOffset.y;

			var isRotated = false;
			if(this._spriteFrame) {
				var textureWidth = locTexture.width;
				var spriteFrameRect = this._spriteFrame._rect;
				if(!this._spriteFrame._rotated) {
					rect.x = rect.x + spriteFrameRect.x;
					rect.y = rect.y + spriteFrameRect.y;
				} else {
					isRotated = true;
					var originalX = rect.x;
					rect.x = rect.y + spriteFrameRect.x;
					rect.y = originalX + spriteFrameRect.y;
				}
			}

			var fontChar = self.getChildByTag(i);

			if (!fontChar) {
				fontChar = new cc.Sprite();
				fontChar.initWithTexture(locTexture, rect, isRotated);
				fontChar._newTextureWhenChangeColor = true;
				this.addChild(fontChar, 0, i);
			} else {
				cmd._updateCharTexture(fontChar, rect, key, isRotated);
			}

			// Apply label properties
			fontChar.opacityModifyRGB = this._opacityModifyRGB;
			cmd._updateCharColorAndOpacity(fontChar);

			var yOffset = locCfg.commonHeight - fontDef.yOffset;
			var fontPos = cc.p(nextFontPositionX + fontDef.xOffset + fontDef.rect.width * 0.5 + kerningAmount,
				nextFontPositionY + yOffset - rect.height * 0.5 * cc.contentScaleFactor());
			fontChar.setPosition(cc.pointPixelsToPoints(fontPos));

			// update kerning
			nextFontPositionX += (fontDef.xAdvance) + kerningAmount;
			nextFontPositionX += this._additionalKerning*2;//字符间距。7间距*2，效果才才相同
			prev = key;

			if (longestLine < nextFontPositionX)
				longestLine = nextFontPositionX;
		}

		//If the last character processed has an xAdvance which is less that the width of the characters image, then we need
		// to adjust the width of the string to take this into account, or the character will overlap the end of the bounding box
		if (fontDef && fontDef.xAdvance < fontDef.rect.width)
			tmpSize.width = longestLine - fontDef.xAdvance + fontDef.rect.width;
		else
			tmpSize.width = longestLine;
		tmpSize.height = totalHeight;
		self.setContentSize(cc.sizePixelsToPoints(tmpSize));
	};

	pBMF.updateString = function (fromUpdate) {
		var self = this;
		var locChildren = self._children;
		if (locChildren) {
			var length = locChildren.length;
			for (var i = 0, li = length; i < li; i++) {
				var node = locChildren[i];
				if (node) node.visible = false;
			}
		}
		if (self._config) {
			if(self._string && self._string.length > 0) {
				self.createFontChars();
			}
		}

		if (!fromUpdate)
			self.updateLabel();
	};

	pBMF._checkWarp = function (strArr, i, maxWidth, initStringWrapNum) {
		var self = this;
		var text = strArr[i];
		var curLength = 0;
		for (var strArrIndex = 0; strArrIndex < i; strArrIndex++) {
			curLength += strArr[strArrIndex].length;
		}

		curLength = curLength + i - initStringWrapNum; // add the wrap line num

		var allWidth = self._getCharsWidth(curLength, strArr[i].length - 1);

		if (allWidth > maxWidth && text.length > 1) {
			var fuzzyLen = text.length * ( maxWidth / allWidth ) | 0;
			var tmpText = text.substr(fuzzyLen);
			var width = allWidth - this._getCharsWidth(curLength + fuzzyLen, tmpText.length - 1);
			var sLine;
			var pushNum = 0;

			//Increased while cycle maximum ceiling. default 100 time
			var checkWhile = 0;

			//Exceeded the size
			while (width > maxWidth && checkWhile++ < 100) {
				fuzzyLen *= maxWidth / width;
				fuzzyLen = fuzzyLen | 0;
				tmpText = text.substr(fuzzyLen);
				width = allWidth - this._getCharsWidth(curLength + fuzzyLen, tmpText.length - 1);
			}

			checkWhile = 0;

			//Find the truncation point
			while (width < maxWidth && checkWhile++ < 100) {
				if (tmpText) {
					var exec = cc.LabelTTF._wordRex.exec(tmpText);
					pushNum = exec ? exec[0].length : 1;
					sLine = tmpText;
				}
				if (self._lineBreakWithoutSpaces) {
					pushNum = 0;
				}
				fuzzyLen = fuzzyLen + pushNum;
				tmpText = text.substr(fuzzyLen);
				width = allWidth - this._getCharsWidth(curLength + fuzzyLen, tmpText.length - 1);
			}

			fuzzyLen -= pushNum;
			if (fuzzyLen === 0) {
				fuzzyLen = 1;
				sLine = sLine.substr(1);
			}

			var sText = text.substr(0, fuzzyLen), result;

			//symbol in the first
			if (cc.LabelTTF.wrapInspection) {
				if (cc.LabelTTF._symbolRex.test(sLine || tmpText)) {
					result = cc.LabelTTF._lastWordRex.exec(sText);
					pushNum = result ? result[0].length : 0;
					if (self._lineBreakWithoutSpaces) {
						pushNum = 0;
					}
					fuzzyLen -= pushNum;

					sLine = text.substr(fuzzyLen);
					sText = text.substr(0, fuzzyLen);
				}
			}

			//To judge whether a English words are truncated
			if (cc.LabelTTF._firsrEnglish.test(sLine)) {
				result = cc.LabelTTF._lastEnglish.exec(sText);
				if (result && sText !== result[0]) {
					pushNum = result[0].length;
					if (self._lineBreakWithoutSpaces) {
						pushNum = 0;
					}
					fuzzyLen -= pushNum;
					sLine = text.substr(fuzzyLen);
					sText = text.substr(0, fuzzyLen);
				}
			}
			strArr[i] = sLine || tmpText;
			strArr.splice(i, 0, sText);
		}
	};

	pBMF.updateLabel = function () {
		var self = this;
		self.string = self._initialString;

		var i, j, characterSprite;
		// process string
		// Step 1: Make multiline
		if (self._width > 0) {
			var stringArr = self.string.split('\n');
			var wrapString = "";
			var newWrapNum = 0;
			var oldArrLength = 0;
			for (i = 0; i < stringArr.length; i++) {
				oldArrLength = stringArr.length;
				this._checkWarp(stringArr, i, self._width * this._scaleX, newWrapNum);
				if (oldArrLength < stringArr.length) {
					newWrapNum++;
				}
				if (i > 0) {
					wrapString += "\n";
				}
				wrapString += stringArr[i];
			}
			wrapString = wrapString + String.fromCharCode(0);
			self._setString(wrapString, false);
		}
		// Step 2: Make alignment
		if (self._alignment !== cc.TEXT_ALIGNMENT_LEFT) {
			i = 0;

			var lineNumber = 0;
			var strlen = self._string.length;
			var last_line = [];

			for (var ctr = 0; ctr < strlen; ctr++) {
				if (self._string[ctr].charCodeAt(0) === 10 || self._string[ctr].charCodeAt(0) === 0) {
					var lineWidth = 0;
					var line_length = last_line.length;
					// if last line is empty we must just increase lineNumber and work with next line
					if (line_length === 0) {
						lineNumber++;
						continue;
					}
					var index = i + line_length - 1 + lineNumber;
					if (index < 0) continue;

					var lastChar = self.getChildByTag(index);
					if (lastChar == null)
						continue;
					lineWidth = lastChar.getPositionX() + lastChar._getWidth() / 2;

					var shift = 0;
					switch (self._alignment) {
						case cc.TEXT_ALIGNMENT_CENTER:
							shift = self.width / 2 - lineWidth / 2;
							break;
						case cc.TEXT_ALIGNMENT_RIGHT:
							shift = self.width - lineWidth;
							break;
						default:
							break;
					}

					if (shift !== 0) {
						for (j = 0; j < line_length; j++) {
							index = i + j + lineNumber;
							if (index < 0) continue;
							characterSprite = self.getChildByTag(index);
							if (characterSprite)
								characterSprite.x += shift;
						}
					}

					i += line_length;
					lineNumber++;

					last_line.length = 0;
					continue;
				}
				last_line.push(self._string[i]);
			}
		}
	};
	////////////////////////////////////////////////////////////////////////////
	pBMF.setBMFontSize = function (size) {
		let scale = size * cc.contentScaleFactor() / this._config.commonHeight;
		//this._bmfontScale = scale;
		this.setScale(scale);
	};
	pBMF.setBMFontFilePath = function (fntFile) {
		this.setFntFile(fntFile)
	};
	////////////////////////////////////////////////////////////////////////////
	pBMF.updateContent = function () {

	};

	pBMF.setAdditionalKerning = function (space) {
		if (this._additionalKerning !== space) {
			this._additionalKerning = space;
			this.updateLabel();
		}
	};
	pBMF.__setAlignment = pBMF.setAlignment;
	pBMF.setAlignment = function (hAlignment, vAlignment) {
		this.__setAlignment(hAlignment);

	};

	pBMF.enableBold = function() {

	};
	pBMF.enableGlow = function() {

	};
	pBMF.enableItalics = function() {

	};
	pBMF.enableOutline = function() {

	};
	pBMF.enableShadow = function() {

	};
	pBMF.enableStrikethrough = function() {

	};
	pBMF.enableUnderline = function() {

	};
	pBMF.enableWrap = function (config) {

	};

	pBMF.setLineSpacing = function (config) {

	};
	pBMF.setMaxLineWidth = function (width) {

	};
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
